PCIe学习笔记之pcie结构和配置空间 |
您所在的位置:网站首页 › pci configuration › PCIe学习笔记之pcie结构和配置空间 |
PCIe概述
PCI Express,是计算机总线PCI的一种,它沿用现有的PCI编程概念及通信标准,但建基于更快的串行通信系统。 PCIE总线使用的是高速差分总线,并采用端到端的连接方式, 现在的高速总线基本上都是串行总线,这样可以使用更高的时钟频率。 当前pcie协议支持到5.0版本,不同PCIe版本对应的传输速率如下: PCIe 版本编码传输速率(GT/S)x4吞吐量(MB/s)1.08b/10b2.512.08b/10b523.0128b/130b8~44.0128b/130b16~85.0128b/130b32~16 pcie总线的拓扑结构
PCIe endponit: PCIe终端设备,是PCIe树形结构的叶子节点。比如网卡,NVME卡,显卡都是PCIe ep设备。 BDF(Bus,device,function)构成了每个PCIe设备节点的身份标识。 PCIe配置空间PCI有三个相互独立的物理地址空间:memory地址空间、I/O地址空间和配置空间。这三个地址空间都是采用唯一的地址进行寻址,比如我们使用地址0x100时需要指定这个地址在哪个地址空间,配置空间,I/O地址空间和memory地址空间的0x100偏移,对应的是不同的存储位置。 我们可以读取配置空间获得设备的信息,也可以通过配置空间来配置设备,通过pci设备的id和配置空间的偏移地址, 软件可以来访问具体的寄存器。 PCIe设备的每一个功能(function)都对应一个独立的配置空间, pcie的配置空间布局如下: PCI标准配置空间分type0和type1两种。type0主要是针对PCI的endpoint设备,type1主要是针对PCI bridge, switch。 Command: PCI设备命令寄存器, 在pci设备使能pci_enable_device时会配置该寄存器。主要时负责使能或关闭pci设备的I/O 访问,memory访问和INTx中断等。 举个例子: 上电时,系统软件首先会读取PCIe设备的BAR0,得到数据: BAR地址寄存器负责PCI设备内部空间的映射, 有了这个映射,CPU可以做到对pcie设备空间的访问。 比如CPU想去读PCIe设备的数据,系统启动时通过BAR地址把PCIe设备空间映射到内存空间,CPU要访问该PCIe设备空间,只需访问对应的内存空间。CPU发出一个物理地址,RC检查该地址,如果发现该内存空间地址是某个PCIe设备空间的映射,就会触发其产生TLP,去访问对应的PCIe设备,读取或者写入PCIe设备。 Capbility Pointer: PCI capbility的地址偏移, capbility用于表示pci设备支持的能力。该寄存器存放Capabilities 结构链表的头指针。在一个PCIe 设备中,可能含有多个Capability 结构,这些寄存器组成一个链表: Interrupt Pin: PCI设备中断引脚,支持INTX A/B/C/D四个中断引脚。 Interrupt line: 表示当前PCI设备使用的中断号。 type0 独有的寄存器: CardBus CISpointer: 只读,可选,用于表明访问CIS(card info structure)的地址空间, 通常不会涉及。 Subsystem ID/ subsystem Vendor ID: 子系统和子厂商ID,可以结合Device ID和Vendor ID来组成完成的PCI设备标识。 Max_lat: 设备期望的最大延时,只读。 Min_Gbt: 设备期望的最小延时,只读。 type1 独有的寄存器: Primary Bus Number: 表示PCI设备挂在的PCI总线号。 Subordinate Bus Number: PCI桥可以管理其下的PCI总线子树。其中Subordinate Bus Number寄存器存放当前PCI子树中,编号最大的PCI总线号。 Secondary Bus Number: 存放当前PCI桥Secondary Bus使用的总线号,这个PCI总线号也是该PCI桥管理的PCI子树中编号最小的PCI总线号 Secondary Latency Timer: PCI桥下游的延时寄存器,和Latency Timer寄存器的含义相近 I/O base: 表示IO寻址的基地址, 低4bit只读,所以PCI设备默认IO寻址4K对齐,高4bit可写。 I/O limit: IO寻址的上限,高4bit可写,低4bit为全F,所以io寻址上限是I/O limit地址 + 4K. Secondary status: 保存PCI下游总线和设备的状态。 Memory Base: 表示memory寻址的基地址。 Memory Limit: 表示memroy寻址的上限,和IO limit类似。 Prefetchable Memory Base: 可预期内存的基地址 Prefetchable Memory Limit: 可预期内存寻址的上限。 Bridge Control Register:管理PCI桥的Secondary Bus, 可以控制 Secondary Bus的 Reset。 2. PCI capbility结构(64 ~ 256bytes)这段空间主要存放一些与MSI/MSI-X中断机制和电源管理相关的capbility。 在内核include/uapi/linux/pci_regs.h归纳了capabilityID和各个capability名称的对应关系: /* Capability lists */ #define PCI_CAP_LIST_ID 0 /* Capability ID */ #define PCI_CAP_ID_PM 0x01 /* Power Management */ #define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */ #define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */ #define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */ #define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */ #define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */ #define PCI_CAP_ID_PCIX 0x07 /* PCI-X */ #define PCI_CAP_ID_HT 0x08 /* HyperTransport */ #define PCI_CAP_ID_VNDR 0x09 /* Vendor specific */ #define PCI_CAP_ID_DBG 0x0A /* Debug port */ #define PCI_CAP_ID_CCRC 0x0B /* CompactPCI Central Resource Control */ #define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */ #define PCI_CAP_ID_SSVID 0x0D /* Bridge subsystem vendor/device ID */ #define PCI_CAP_ID_AGP3 0x0E /* AGP Target PCI-PCI bridge */ #define PCI_CAP_ID_EXP 0x10 /* PCI Express */ #define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ #define PCI_CAP_ID_AF 0x13 /* PCI Advanced Features */ #define PCI_CAP_LIST_NEXT 1 /*Next capability in the list */ #define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */ #define PCI_CAP_SIZEOF 4 3. PCIe 扩展配置空间(256 ~ 4K bytes)这段空间主要存放PCIe独有的一些capbility结构,如AER, SR-IOV等。 pcie扩展能力定义如下: /* Extended Capabilities (PCI-X 2.0 and Express) */ #define PCI_EXT_CAP_ID(header) (header & 0x0000ffff) #define PCI_EXT_CAP_VER(header) ((header >> 16) & 0xf) #define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc) #define PCI_EXT_CAP_ID_ERR 0x01 /* Advanced Error Reporting */ #define PCI_EXT_CAP_ID_VC 0x02 /* Virtual Channel Capability */ #define PCI_EXT_CAP_ID_DSN 0x03 /* Device Serial Number */ #define PCI_EXT_CAP_ID_PWR 0x04 /* Power Budgeting */ #define PCI_EXT_CAP_ID_RCLD 0x05 /* Root Complex Link Declaration */ #define PCI_EXT_CAP_ID_RCILC 0x06 /* Root Complex Internal Link Control */ #define PCI_EXT_CAP_ID_RCEC 0x07 /* Root Complex Event Collector */ #define PCI_EXT_CAP_ID_MFVC 0x08 /* Multi-Function VC Capability */ #define PCI_EXT_CAP_ID_VC9 0x09 /* same as _VC */ #define PCI_EXT_CAP_ID_RCRB 0x0A /* Root Complex RB? */ #define PCI_EXT_CAP_ID_VNDR 0x0B /* Vendor-Specific */ #define PCI_EXT_CAP_ID_CAC 0x0C /* Config Access - obsolete */ #define PCI_EXT_CAP_ID_ACS 0x0D /* Access Control Services */ #define PCI_EXT_CAP_ID_ARI 0x0E /* Alternate Routing ID */ #define PCI_EXT_CAP_ID_ATS 0x0F /* Address Translation Services */ #define PCI_EXT_CAP_ID_SRIOV 0x10 /* Single Root I/O Virtualization */ #define PCI_EXT_CAP_ID_MRIOV 0x11 /* Multi Root I/O Virtualization */ #define PCI_EXT_CAP_ID_MCAST 0x12 /* Multicast */ #define PCI_EXT_CAP_ID_PRI 0x13 /* Page Request Interface */ #define PCI_EXT_CAP_ID_AMD_XXX 0x14 /* Reserved for AMD */ #define PCI_EXT_CAP_ID_REBAR 0x15 /* Resizable BAR */ #define PCI_EXT_CAP_ID_DPA 0x16 /* Dynamic Power Allocation */ #define PCI_EXT_CAP_ID_TPH 0x17 /* TPH Requester */ #define PCI_EXT_CAP_ID_LTR 0x18 /* Latency Tolerance Reporting */ #define PCI_EXT_CAP_ID_SECPCI 0x19 /* Secondary PCIe Capability */ #define PCI_EXT_CAP_ID_PMUX 0x1A /* Protocol Multiplexing */ #define PCI_EXT_CAP_ID_PASID 0x1B /* Process Address Space ID */ #define PCI_EXT_CAP_ID_DPC 0x1D /* Downstream Port Containment */ #define PCI_EXT_CAP_ID_L1SS 0x1E /* L1 PM Substates */ #define PCI_EXT_CAP_ID_PTM 0x1F /* Precision Time Measurement */ #define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PTM #define PCI_EXT_CAP_DSN_SIZEOF 12 #define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40 PCIE配置空间的访问CPU可以通过访问BAR地址读取PCIe的设备空间,但是我们需要读取到配置空间才能获取BAR,那么怎么访问PCIe的配置空间呢? ARM使用ECAM的方式访问PCIe配置空间。ECAM是一个将配置空间映射到MEMORY空间的规则。硬件根据ECAM的方式将某个Memory空间映射给PCI配置空间,CPU访问对应的memory空间即可以操作PCIe配置空间。 映射的地址定义如下: 在ACPI规范中,需要通过MCFG表上报ECAM的地址映射 查看pci设备拓扑结构: lspci -tv ![]() 举个例子: 查看设备的详细信息 所以40: 0d 48 ===> 表示偏移0x40的位置的capability id是0xd(SSVID); 它指向的下一个capability位于0x48处,偏移0x48的位置的capability id是0x1(即power management); 它指向的下一个capabity位于0x50处,偏移0x50的位置的capability id是0x10(MSI);它指向的下一个capability位于0x8c处, 偏移0x8c的位置的capability id为0x0, 查找结束。 得到的结果是可以与lspci的结果对应的: 可以用setpci命令修改配置空间 setpci -s 00:00.0 0x地址.L=0x值 --修改设备地址的数值,一次修改4个字节举个例子, 上面有提到往pci设备的BAR寄存器写全1可以计算BAR空间的大小需求 [root@localhost ~]# lspci -s 02:01.0 -x 02:01.0 Ethernet controller: Intel Corporation 82545EM Gigabit Ethernet Controller (Copper) (rev 01) 00: 86 80 0f 10 17 01 30 02 01 00 00 02 10 00 00 00 10: 04 00 5c fd 00 00 00 00 04 00 ff fd 00 00 00 00 20: 01 20 00 00 00 00 00 00 00 00 00 00 ad 15 50 07 30: 00 00 00 00 dc 00 00 00 00 00 00 00 07 01 ff 00网卡设备的pci配置头空间如上所示, 通过setpci --dumpregs可以查看寄存器偏移 [root@localhost ~]# setpci --dumpregs cap pos w name 00 W VENDOR_ID 02 W DEVICE_ID 04 W COMMAND 06 W STATUS 08 B REVISION 09 B CLASS_PROG 0a W CLASS_DEVICE 0c B CACHE_LINE_SIZE 0d B LATENCY_TIMER 0e B HEADER_TYPE 0f B BIST 10 L BASE_ADDRESS_0 14 L BASE_ADDRESS_1 18 L BASE_ADDRESS_2 1c L BASE_ADDRESS_3 20 L BASE_ADDRESS_4 24 L BASE_ADDRESS_5 ......BAR0的偏移是0x10, 通过setpci命令写该地址全F PCI桥与PCI设备的配置空间 老男孩读PCIe之六:配置和地址空间 PCI.EXPRESS系统体系结构标准教材 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |